package ru.urfc.portal.dao.impl;

import java.util.Date;
import java.util.List;

import javax.ejb.EJB;
import javax.ejb.Stateless;

import ru.urfc.portal.dao.BalanceDao;
import ru.urfc.portal.dao.BasePersistence;
import ru.urfc.portal.dao.Paging;
import ru.urfc.portal.dao.SpectrId;
import ru.urfc.portal.dao.filter.Filter;
import ru.urfc.portal.dao.filter.Operator;
import ru.urfc.portal.model.SpectrObjectWithContragent;
import ru.urfc.portal.model.accounting.Balance;
import ru.urfc.portal.model.accounting.InvoiceFacture;
import ru.urfc.portal.model.accounting.Payment;

@Stateless
public class BalanceDaoImpl extends BaseDao implements BalanceDao {

	@EJB BasePersistence basePersistence;

	@Override
	public Balance getLastBalanceBefore(SpectrId contragentId, Integer year, Integer month, Integer day) {
		
		return oneOrNull(basePersistence.findWhere(contragentId.getBranch(), Balance.class,
				format(	"this.contragent.id = ?1 and" +
						" (this.year < ?2 or (this.year = ?2 and this.month {0} ?3))",
						day == 1? "<": "<="),
						"this.year DESC, this.month DESC", Paging.ONE, contragentId.getId(), year, month));
	}

	@Override
	public List<Balance> getBalances(SpectrId contragentId,
			Integer fromYear, Integer fromMonth, Integer fromDay,
			Integer toYear, Integer toMonth, Integer toDay) {
		return basePersistence.findWhere(contragentId.getBranch(), Balance.class,
				format(	"this.contragent.id = ?1" +
						" and (this.year > ?2 or (this.year = ?2 and this.month {0} ?3))" +
						" and (this.year < ?4 or (this.year = ?4 and this.month <= ?5))",
						fromDay == 1? ">=": ">"), null, 
				Paging.NULL_OBJECT, contragentId.getId(), fromYear, fromMonth, toYear, toMonth);
	}
	
	@Override
	public List<InvoiceFacture> getInvoiceFactures(SpectrId contragentId, Date fromDate, Date toDate) {
		return findInInterval(InvoiceFacture.class, contragentId, fromDate, toDate); 
	}

	@Override
	public List<Payment> getPayments(SpectrId contragentId, Date fromDate, Date toDate) {
		return findInInterval(Payment.class, contragentId, fromDate, toDate);
	}

	private <T extends SpectrObjectWithContragent> List<T> findInInterval(Class<T> klass,
			SpectrId contragentId, Date date, Date lastDate) {
		Filter filter = new Filter("contragent.id", contragentId.getId());
		filter.add("date", Operator.GREAT_OR_EQUAL, date);
		filter.add("date", Operator.LESS_OR_EQUAL, lastDate);
		return basePersistence.find(contragentId.getBranch(), klass, filter);
	}

}
